package com.anjie.powerproject.util;

import com.anjie.powerproject.pojo.dto.DynamicPropertyDetail;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 表达式和前端SOP相互转换
 */
public class ExpressUtil {

    /**
     * 表达式转DynamicPropertyWrap
     * 约定：表达式一定是类似以下的结构
     * devVal('yc467') > 20 and devVal('yc4869') > 20
     *
     * 所以使用空格split之后，尺寸一定会是4 * n + 3，如果不是的话直接抛出异常
     */
    public static List<DynamicPropertyDetail> expressToDTO(String express) {
        if (StringUtils.isEmpty(express)) {
            return null;
        }
        String[] expressSplit = express.split(" ");
        if ((expressSplit.length - 3) % 4 != 0) {
            throw new RuntimeException("数据库中存储的表达式异常，可能被非法修改!");
        }

        // 正式进行解析
        List<DynamicPropertyDetail> details = new ArrayList<>();

        int limit = (expressSplit.length - 3) / 4 + 1;

        for (int i = 0; i < limit; i++) {
            int idx = i * 4;

            DynamicPropertyDetail detail = new DynamicPropertyDetail();
            detail.setPointId(pointIdConvert(expressSplit[idx]));
            detail.setSymbol(expressSplit[idx + 1]);
            detail.setValue(Double.parseDouble(expressSplit[idx + 2]));

            if (i < limit - 1) {
                detail.setRel(expressSplit[idx + 3]);
            }

            details.add(detail);
        }

        return details;
    }

    private static Integer pointIdConvert(String pointId) {
        if (StringUtils.isEmpty(pointId)) {
            return null;
        }

        int startIdx = pointId.indexOf("(");
        int endIdx = pointId.indexOf(")");

        if (startIdx + 1 == endIdx) {
            return null;
        }

        String num = pointId.substring(startIdx + 1, endIdx);

        return Integer.parseInt(num);
    }

    private static String devCodeConvert(String devCode) {
        if (StringUtils.isEmpty(devCode)) {
            return devCode;
        }

        String[] dev = devCode.split("'");
        if (dev.length < 2) {
            return devCode;
        }

        return dev[1];
    }

    private static Integer relConvert(String rel) {
        if ("AND".equalsIgnoreCase(rel)) {
            return 0;
        } else {
            return 1;
        }
    }

    private static String relConvert(Integer rel) {
        if (Objects.equals(rel, 0)) {
            return "AND";
        } else {
            return "OR";
        }
    }

    /**
     * DynamicPropertyWrap转表达式
     */
    public static String dtoToExpress(List<DynamicPropertyDetail> details) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < details.size(); i++) {
            DynamicPropertyDetail detail = details.get(i);
            sb.append("devVal(").append(detail.getPointId()).append(") ");
            sb.append(detail.getSymbol()).append(" ");
            sb.append(detail.getValue());

            if (i < details.size() - 1) {
                sb.append(" ").append(detail.getRel()).append(" ");
            }
        }
        return sb.toString();
    }
}
